/*
   Copyright 2009 the original author or authors

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

package com.googlecode.kohmori.reportgen;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.xml.sax.ContentHandler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;


/**
 * This class is an implementation of ContentHandler which acts as a proxy to
 * another ContentHandler and has the purpose to provide a few handy methods 
 * that make life easier when generating SAX events.
 * <br>
 * Note: This class is only useful for simple cases with no namespaces. 
 */
public class AdvancedContentHandlerProxy extends EasyGenerationContentHandlerProxy {

    private SimpleDateFormat defaultDateFormat;
    
    /**
     * Main constructor.
     * @param forwardTo ContentHandler to forward the SAX event to.
     */
    public AdvancedContentHandlerProxy(ContentHandler forwardTo) {
        super(forwardTo);
        defaultDateFormat = new SimpleDateFormat("MM/dd/yyyy");
    }

    public void setDefaultDateFormat(SimpleDateFormat defaultDateFormat) {
        this.defaultDateFormat = defaultDateFormat;
    }

    /**
     * Utility helper to create an Attribute in a manner that works 
     * both for XSLT and for Apache FOP.
     */
    public static AttributesImpl createAttribute(String name, String value) {
       AttributesImpl atts = new AttributesImpl();
       atts.addAttribute("", name, name, "", value);
       return atts;
    }
    
    /**
     * Sends notifications for a whole element with Date content.
     * @param name Name for the element.
     * @param value Content of the element.
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     */
    public void element(String name, Date dateVal) throws SAXException {
        element(name, dateVal, EMPTY_ATTS);
    }


    /**
     * Sends notifications for a whole element with Date content.
     * @param name Name for the element.
     * @param value Content of the element.
     * @param atts The attributes attached to the element. If there are no 
     * attributes, it shall be an empty Attributes object. 
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     */
    public void element(String name, Date dateVal, Attributes atts) throws SAXException {
        element(name, dateVal, atts, defaultDateFormat);
    }

    /**
     * Sends notifications for a whole element with int content.
     * @param name Name for the element.
     * @param value Content of the element.
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     */
    public void element(String name, int intVal) throws SAXException {
        element(name, intVal, EMPTY_ATTS);
    }


    /**
     * Sends notifications for a whole element with int content.
     * @param name Name for the element.
     * @param value Content of the element.
     * @param atts The attributes attached to the element. If there are no 
     * attributes, it shall be an empty Attributes object. 
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     */
    public void element(String name, int intVal, Attributes atts) throws SAXException {
        element(name, (new Integer(intVal)).toString(), atts);
    }

    /**
     * Sends notifications for a whole element with float content.
     * @param name Name for the element.
     * @param value Content of the element.
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     */
    public void element(String name, float floatVal) throws SAXException {
        element(name, floatVal, EMPTY_ATTS);
    }


    /**
     * Sends notifications for a whole element with float content.
     * @param name Name for the element.
     * @param value Content of the element.
     * @param atts The attributes attached to the element. If there are no 
     * attributes, it shall be an empty Attributes object. 
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     */
    public void element(String name, float floatVal, Attributes atts) throws SAXException {
        element(name, (new Float(floatVal)).toString(), atts);
    }

    /**
     * Sends notifications for a whole element with some String content.
     * @param name Name for the element.
     * @param value Content of the element.
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     */
    public void element(String name, Date dateVal, SimpleDateFormat sdf) throws SAXException {
        element(name, dateVal, EMPTY_ATTS, sdf);
    }


    /**
     * Sends notifications for a whole element with some String content.
     * @param name Name for the element.
     * @param value Content of the element.
     * @param atts The attributes attached to the element. If there are no 
     * attributes, it shall be an empty Attributes object. 
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     */
    public void element(String name, Date dateVal, Attributes atts, SimpleDateFormat sdf) throws SAXException {
        String strValue = null;
        
        startElement(name, atts);
        if (dateVal != null) {
            strValue = sdf.format(dateVal).toUpperCase();
            characters(strValue.toCharArray(), 0, strValue.length());
        }
        endElement(name);
    }
    
    /**
     * Sends notifications for a whole element with char content.
     * @param name Name for the element.
     * @param value Content of the element.
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     */
    public void element(String name, char charVal) throws SAXException {
        element(name, charVal, EMPTY_ATTS);
    }


    /**
     * Sends notifications for a whole element with char content.
     * @param name Name for the element.
     * @param value Content of the element.
     * @param atts The attributes attached to the element. If there are no 
     * attributes, it shall be an empty Attributes object. 
     * @throws SAXException Any SAX exception, possibly wrapping another exception.
     */
    public void element(String name, char charVal, Attributes atts) throws SAXException {
        element(name, "" + charVal, atts);
    }
}